package com.demo.gateway.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONArray;
import com.demo.gateway.pojo.AutoRegisterGatewayRoutesDTO;
import com.demo.gateway.pojo.AutoRegisterPathDTO;
import com.demo.gateway.pojo.GatewayRouteDO;
import com.demo.gateway.routes.filters.FilterFactory;
import com.demo.gateway.routes.predicate.PredicateEnums;
import com.demo.gateway.routes.predicate.PredicateFactory;
import com.demo.gateway.service.IGateWayRoute;
import com.demo.gateway.util.RouteIdUtil;
import com.demo.gateway.util.UriUtil;
import com.demo.gateway.vo.core.DataVO;
import com.demo.gateway.vo.core.PageVO;
import com.demo.gateway.vo.core.ReturnVO;

import lombok.extern.slf4j.Slf4j;

/**
 * @author: demo
 * @date: 2020年6月19日
 * @Document : 路由服务类
 */
@Slf4j
@RestController
public class GatewayRouteController {
    @Autowired
	private IGateWayRoute dynamicGatewayRouteServcie;
    
	@Autowired
	private PredicateFactory predicateFactory;
	@Autowired
	private FilterFactory filterFactory;
    /**
     * 路由添加
     * @param route
     * @return
     */
	@PostMapping("route/add")
	public  ReturnVO addRoute(@RequestBody GatewayRouteDO route) {
		String uri = route.getUri();
		String proxy = route.getProxy();
		String location = UriUtil.formatUrl(route.getLocation());
		if (StringUtils.isBlank(uri)) {
			route.setUri(proxy);
		}
		String id = route.getId();
		if (StringUtils.isBlank(id)) {
			route.setId(RouteIdUtil.nextMd5Id(proxy, location));
		}
		predicateFactory.args().put("pattern", location);
		List<FilterDefinition> filterDefinitions = filterFactory.asFiltersList(filterFactory.getRedisGatewayFilter(),filterFactory.getHystrixGatewayFilter());
		List<PredicateDefinition> predicateDefinitions = predicateFactory.getPredicates(PredicateEnums.Path);
		route.setFilters(filterDefinitions);
		route.setPredicates(predicateDefinitions);
		route.setStartTime(new Date());
		return dynamicGatewayRouteServcie.addRoute(route,true);
	}
	/**
	 * 路由批量添加
	 * @param routes
	 * @return
	 */
	@PostMapping("route/addBatch")
	public  ReturnVO addBatch(@RequestBody AutoRegisterGatewayRoutesDTO  registerGatewayRoutes) {
		
		List<GatewayRouteDO> routeLists=new ArrayList<GatewayRouteDO>();
		List<AutoRegisterPathDTO> paths=   registerGatewayRoutes.getPaths();
	
		String applicationName=registerGatewayRoutes.getApplicationName();
		Integer  status=registerGatewayRoutes.getDefaultRelease();
		String uri=registerGatewayRoutes.getRegisterGateway();
		Date  startTime=registerGatewayRoutes.getStartTime();
		String version=registerGatewayRoutes.getVersion();
		paths.forEach((regitster)->{
			String  location=UriUtil.formatUrl(regitster.getPath());
			log.warn("--------------------{}",location);
			predicateFactory.args().put("pattern",location);
			List<PredicateDefinition> predicateDefinitions = predicateFactory.getPredicates(PredicateEnums.Path);
			List<FilterDefinition> filterDefinitions = filterFactory.asFiltersList(filterFactory.getRedisGatewayFilter(),filterFactory.getHystrixGatewayFilter());
			GatewayRouteDO routeBean=new GatewayRouteDO();
			routeBean.setApplicationName(applicationName);
			routeBean.setStatus(status);
			routeBean.setUri(uri);
			routeBean.setFilters(filterDefinitions);
			routeBean.setPredicates(predicateDefinitions);
			routeBean.setStartTime(startTime);
			routeBean.setVersion(version);
			routeBean.setId(RouteIdUtil.nextMd5Id(uri, location));
			routeBean.setMethodType(regitster.getMethodType());
			routeBean.setDescription(location);
			routeBean.setLocation(location);
			routeLists.add(routeBean);
		});
		log.debug("批量添加路由数量==>{}",routeLists.size());
		return dynamicGatewayRouteServcie.addRoutes(routeLists);
	}
	/**
	 * 路由删除
	 * @param id
	 * @return
	 */
	@PostMapping("route/del/{id}")
	public  ReturnVO deleteRoute(@PathVariable("id")String id) {
		return dynamicGatewayRouteServcie.deleteRoute(id);
	}
	/**
	 * 路由刷新
	 * @return
	 */
	@PostMapping("route/refresh")
	public ReturnVO refresh(){
		 dynamicGatewayRouteServcie.refreshRoute();
		 return ReturnVO.ok("刷新路由成功!");
	}
	/**
	 * 路由redis缓存
	 * @return
	 */
	@PostMapping("route/redis")
	public DataVO<JSONArray> routeRedisHelp(){
		return dynamicGatewayRouteServcie.getGatewayInfo();
	}
	/**
	 * 路由查询所有
	 * @return
	 */
	@PostMapping("route/queryAll")
	public PageVO<GatewayRouteDO> queryAllRoutes(){
		return dynamicGatewayRouteServcie.queryAllGatewayRoutes();
	}
	
	/**
	 * 数据库同步到redis
	 * @return
	 */
	@PostMapping("route/syncRedis")
	public ReturnVO syncRedis(){
		return  dynamicGatewayRouteServcie.database2Redis();
	}
}
